package fr.umlv.escapeir.gesture;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.util.ArrayList;

import fr.umlv.escapeir.painters.Layer;
import fr.umlv.zen2.MotionEvent;

public class GestureHandler implements Layer {

	private final ArrayList<GestureListener> listeners;
	private final ArrayList<Mask> masks;
	
	private Gesture gesture;
	private final Stroke stroke;
	
	private static class GestureHandlerHolder {
		private static final GestureHandler INSTANCE = new GestureHandler();
	}
	
	public static GestureHandler self () {
		return GestureHandlerHolder.INSTANCE;
	}
	
	private GestureHandler() {
		masks = new ArrayList<>();
		listeners = new ArrayList<>();
		masks.add(Masks.LOOPING);
		masks.add(Masks.LINE);
		masks.add(Masks.POINT);
		masks.add(Masks.SQUARE);
		stroke = new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
	}

	@Override
	public void render(Graphics2D painter) {
		if(gesture == null) return;
		
		painter.setColor(Color.BLUE);
		
		if(gesture.isFinished()) {
			if(gesture.isValidMask()) painter.setColor(Color.GREEN);
			else painter.setColor(Color.RED);
			
			gesture.clear();
		}
		painter.setStroke(stroke);
		
		if(gesture.size() >=  2) gesture.drawGesture(painter);
	}

	public void receiveEvent (MotionEvent event) {
		switch(event.getKind()) {
			case ACTION_DOWN:
				gesture = new Gesture();
				break;
			case ACTION_UP:
				gesture.setIsFinished(true);
				findMask(gesture);
				break;
			default:
				break;
		}	
		gesture.addPoint(event.getX(), event.getY());
	}

	private void findMask(Gesture g) {
		for(Mask m: masks) {
			if(m.isValid(g)) {
				dispatchGesture(g);
				return;
			}
		}
	}
	
	private void dispatchGesture(Gesture g) {
		for (GestureListener gl : listeners)
			gl.gestureReceived(g);
	}
	
	public void registerListener (GestureListener gl) {
		listeners.add(gl);
	}
}